package com.xiang.map;

import com.google.common.collect.ArrayListMultimap;
import com.google.common.collect.BiMap;
import com.google.common.collect.HashBasedTable;
import com.google.common.collect.HashBiMap;
import com.google.common.collect.Multimap;
import com.google.common.collect.Range;
import com.google.common.collect.RangeMap;
import com.google.common.collect.Table;
import com.google.common.collect.Table.Cell;
import com.google.common.collect.Tables;
import com.google.common.collect.TreeMultimap;
import com.google.common.collect.TreeRangeMap;
import java.util.Collection;
import java.util.List;
import java.util.Map;
import java.util.Set;
import lombok.extern.slf4j.Slf4j;

@Slf4j
public class GuavaTable {

  public static void main(String[] args) {

    //双key Map
    HashBasedTable<String, String, Integer> table = HashBasedTable.create();
    //存放元素
    table.put("Hydra", "Jan", 20);
    table.put("Hydra", "Feb", 28);

    table.put("Trunks", "Jan", 28);
    table.put("Trunks", "Feb", 16);

  //取出元素
    Integer dayCount = table.get("Hydra", "Feb");
    log.info("取出元素:{}",dayCount);


    //rowKey或columnKey的集合
    Set<String> rowKeySet = table.rowKeySet();
    Set<String> columnKeySet = table.columnKeySet();
    log.info("row:{} \n  cloumn:{} ", rowKeySet,columnKeySet);


    //转换rowKey和columnKey
    Table<String, String, Integer> transpose = Tables.transpose(table);
    Set<Cell<String, String, Integer>> cells = transpose.cellSet();
    cells.forEach(c->{
      log.info("转换后："+c.getRowKey() +" " + c.getColumnKey() + " " + c.getValue());
    });


    // 转为嵌套的Map
    Map<String, Map<String, Integer>> rowMap = table.rowMap();
    Map<String, Map<String, Integer>> columnMap = table.columnMap();
     log.info("行Map:{}  列Map:{}  \n",rowMap,columnMap);


     log.info("------------------------------------------------------------------");



     //BiMap - 双向Map   key和value双向关联的数据结构
    HashBiMap<String, String> biMap = HashBiMap.create();
    biMap.put("Hydra","Programmer");
    biMap.put("Tony","IronMan");
    biMap.put("Thanos","Titan");
    //使用key获取value
    log.info("Tony的value: {} ",biMap.get("Tony"));

    BiMap<String, String> inverse = biMap.inverse();
    log.info("value值获取key: {}",inverse.get("Titan"));

    /**
     * 注：
     *  1、反转后操作的影响： 用inverse方法反转了原来BiMap的键值映射，但是这个反转后的BiMap并不是一个新的对象，它实现了一种视图的关联，所以对反转后的BiMap执行的所有操作会作用于原先的BiMap上
     *  2、value不可重复：双向的BiMap中key和value可以认为处于等价地位，因此在这个基础上加了限制，value也是不允许重复的
     *    若非想把新的key映射到已有的value上，forcePut方法强制替换掉原有的key
     */
    inverse.put("Titan","Thanos-over");
    log.info("反转后取出：{}",biMap);

    Set<String> values = biMap.values();


    //Multimap - 多值Map: 提供了将一个键映射到多个值的形式
    Multimap<String, Integer> multimap = ArrayListMultimap.create();
    multimap.put("day",1);
    multimap.put("day",2);
    multimap.put("day",8);
    multimap.put("month",3);

    log.info("multimap: {}", multimap);

    //取出集合
    Collection<Integer> day = multimap.get("day");
    // ArrayListMultimap<String, Integer> multimap = ArrayListMultimap.create();
    // List<Integer> dayList = multimap.get("day");
    log.info("key的值列表：{}",day);

    //还以创建HashMultimap、TreeMultimap等
    TreeMultimap<Comparable, Comparable> comparableComparableTreeMultimap = TreeMultimap.create();


    //转换为Map
    Map<String, Collection<Integer>> asMap = multimap.asMap();

    //数量问题
    log.info("size: {}",multimap.size());
    log.info("entries size: {}",multimap.entries().size());
    log.info("keySet size: {}",multimap.keySet().size());


    //RangeMap - 范围Map
    RangeMap<Integer, String> rangeMap = TreeRangeMap.create();
    rangeMap.put(Range.closedOpen(0,60),"fail");
    rangeMap.put(Range.closed(60,90),"satisfactory");
    rangeMap.put(Range.openClosed(90,100),"excellent");

    System.out.println(rangeMap.get(59));
    System.out.println(rangeMap.get(60));
    System.out.println(rangeMap.get(90));
    System.out.println(rangeMap.get(91));

    //移除了[70,80]这一闭区间后，再次执行get时返回结果为null
    rangeMap.remove(Range.closed(70,80));
    System.out.println(rangeMap.get(75));



  }

}
